﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.Collections;
using System.Xml;

namespace SSRS_Plus
{
    public partial class frmServers : Form
    {
        SortedList alServers;
        bool boolAddNewFlag = false;
        clsServers ActiveServer;

        public frmServers()
        {
            InitializeComponent();
        }

        private void frmServers_Load(object sender, EventArgs e)
        {
            
            //MessageBox.Show(Security.Encrypt("Asim"));

            ClearTextboxes();
            LoadServerDetails();
            EnabledControls();
        }

        private void LoadServerDetails()
        {
            try
            {
                alServers = new SortedList();
                lstServers.Items.Clear();

                clsServers Srv;

                ServersSection SerSec = (ServersSection)ConfigurationManager.GetSection("ServersSection");

                int i = 0;

                while (i < SerSec.servergroups.Count)
                {
                    Srv = new clsServers();
                    Srv = (clsServers)SerSec.servergroups[i];

                    //Srv.ServerName = Srv.ServerName;
                    //Srv.ServerURL = new Uri(System.Configuration.ConfigurationSettings.AppSettings[Srv.ServerName]);

                    alServers.Add(Srv.ServerName, Srv);

                    lstServers.Items.Add(Srv.ServerName);

                    i++;
                }

                if (lstServers.Items.Count > 0)
                {
                    lstServers.SelectedIndex = 0;
                }
            }
            catch
            {

            }
        }

        private void EnabledControls(bool enable = true)
        {
            try
            {
                lstServers.Enabled = enable;

                txtServerName.ReadOnly = enable;
                txtServerURL.ReadOnly = enable;

                if (ckbWindowsCredential.Checked == true)
                {
                    txtDomain.ReadOnly = true;
                    txtUserName.ReadOnly = true;
                    txtPassWord.ReadOnly = true;
                }
                else
                {
                    txtDomain.ReadOnly = enable;
                    txtUserName.ReadOnly = enable;
                    txtPassWord.ReadOnly = enable;
                }

                btnNew.Enabled = enable;
                if (lstServers.Items.Count == 0)
                {
                    btnEdit.Enabled = false;
                    btnDelete.Enabled = false;
                }
                else
                {
                    btnEdit.Enabled = enable;
                    btnDelete.Enabled = enable;
                }

                btnSave.Enabled = !enable;
                btnCancel.Enabled = !enable;

                ckbWindowsCredential.Enabled = !enable;
            }
            catch { }
        }

        private void btnNew_Click(object sender, EventArgs e)
        {
            boolAddNewFlag = true;
            ClearTextboxes();
            EnabledControls(false);
        }

        /// <summary>
        /// Clear server info from textboxes
        /// </summary>
        private void ClearTextboxes()
        {
            txtServerName.Text = "";
            txtServerURL.Text = "";
            txtDomain.Text = "";
            txtUserName.Text = "";
            txtPassWord.Text = "";
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            ClearTextboxes();
            LoadServerDetails();
            EnabledControls();
            boolAddNewFlag = false;
        }

        private void GetServerDetail(string strServer)
        {
            ActiveServer = new clsServers();
            ActiveServer = (clsServers)alServers[strServer];

            txtServerName.Text = ActiveServer.ServerName;
            txtServerURL.Text = ActiveServer.ServerURL.ToString();
            txtUserName.Text = ActiveServer.UserName;
            txtPassWord.Text = ActiveServer.Password;
            txtDomain.Text = ActiveServer.Domain;

            ckbWindowsCredential.Checked = ActiveServer.WindowsAuthentication;
        }

        private void lstServers_SelectedIndexChanged(object sender, EventArgs e)
        {
            GetServerDetail(lstServers.Text);
        }

        /// <summary>
        /// Check if text box control is empty
        /// </summary>
        /// <param name="control">TextBox control to validate</param>
        /// <param name="errorMessage">(optional) Warning message to display if text box is empty</param>
        /// <returns></returns>
        private bool IsEmpty(TextBox control, String errorMessage = null)
        {
            if (control.Text.Trim() == "")
            {
                if(errorMessage != null)
                    MessageBox.Show(errorMessage, "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);

                control.Focus();
                return true;
            }

            return false;
        }

        /// <summary>
        /// Validate user inputs
        /// </summary>
        /// <returns>Returns true if all controls contain valid content, false otherwise</returns>
        private bool ValidateControls()
        {
            if(IsEmpty(txtServerName, "Server Name cannot be empty!") ||
                IsEmpty(txtServerURL, "SSRS Web Service URL cannot be empty!"))
            {
                return false;
            }

            if (!ckbWindowsCredential.Checked)
            {
                if (IsEmpty(txtDomain, "Domain Name cannot be empty!") ||
                    IsEmpty(txtUserName, "User Name cannot be empty!") ||
                    IsEmpty(txtPassWord, "Password cannot be empty!"))
                {
                    return false;
                }
            }

            if (boolAddNewFlag == true)
            {
                if (alServers[txtServerName.Text.Trim()] != null)
                {
                    MessageBox.Show("Server with same name already exists. Please enter a different name.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    txtServerName.Focus();
                    return false;
                }
            }
            else
            {
                foreach (string strServer in alServers.Keys)
                {
                    if (strServer != ActiveServer.ServerName && strServer == txtServerName.Text.Trim())
                    {
                        MessageBox.Show("Server with same name already exists. Please enter a different name.", "Input Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        txtServerName.Focus();
                        return false;
                    }
                }
            }

            return true;
        }

        private void btnEdit_Click(object sender, EventArgs e)
        {
            boolAddNewFlag = false;
            EnabledControls(false);
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                if (ValidateControls())
                {
                    AddModifyServer();
                    boolAddNewFlag = false;
                    LoadServerDetails();
                    EnabledControls();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }


        private void AddModifyServer()
        {
            clsServers UpdateServer = new clsServers();

            UpdateServer.ServerMode = cmdServerMode.Text;
            UpdateServer.ServerName = txtServerName.Text.Trim();
            UpdateServer.ServerURL = new Uri(txtServerURL.Text.Trim());
            UpdateServer.WindowsAuthentication = ckbWindowsCredential.Checked;
            UpdateServer.UserName = txtUserName.Text.Trim();
            UpdateServer.Domain = txtDomain.Text.Trim();
            UpdateServer.Password =  Security.Encrypt(txtPassWord.Text.Trim());

            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);

            if (boolAddNewFlag)
            {
                XmlNode xn = xDoc.SelectSingleNode("configuration/ServersSection/servergroups");

                XmlElement xnNew = xDoc.CreateElement("server", null);

                xnNew.SetAttribute("ServerName", UpdateServer.ServerName);
                xnNew.SetAttribute("ServerURL", UpdateServer.ServerURL.ToString());
                xnNew.SetAttribute("WindowsAuthentication", UpdateServer.WindowsAuthentication.ToString());
                xnNew.SetAttribute("Domain", UpdateServer.Domain.ToString());
                xnNew.SetAttribute("UserName", UpdateServer.UserName);
                xnNew.SetAttribute("Password", UpdateServer.Password.ToString());
                xnNew.SetAttribute("ServerMode", UpdateServer.ServerMode);

                xn.AppendChild(xnNew);
            }
            else
            {
                foreach (XmlNode xn in xDoc.SelectNodes("configuration/ServersSection/servergroups/server"))
                {
                    if (xn.Attributes[0].Value == ActiveServer.ServerName)
                    {
                        xn.Attributes[0].Value = UpdateServer.ServerName;
                        xn.Attributes[1].Value = UpdateServer.ServerURL.ToString();

                        xn.Attributes[2].Value = UpdateServer.WindowsAuthentication.ToString();
                        xn.Attributes[3].Value = UpdateServer.Domain.ToString();
                        xn.Attributes[4].Value = UpdateServer.UserName.ToString();
                        xn.Attributes[5].Value = UpdateServer.Password.ToString();

                        xn.Attributes[6].Value = UpdateServer.ServerMode;

                        break;
                    }
                }
            }

            xDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);

            ConfigurationManager.RefreshSection("ServersSection");
        }

        private void ckbWindowsCredential_CheckedChanged(object sender, EventArgs e)
        {
            if (btnNew.Enabled == false)
            {
                txtDomain.Text = "";
                txtPassWord.Text = "";
                txtUserName.Text = "";

                txtDomain.ReadOnly = ckbWindowsCredential.Checked;
                txtUserName.ReadOnly = ckbWindowsCredential.Checked;
                txtPassWord.ReadOnly = ckbWindowsCredential.Checked;
            }
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Are you sure want to delete " + lstServers.Text + " Server?", "Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
            {
                XmlDocument xDoc = new XmlDocument();
                xDoc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);

                foreach (XmlNode xn in xDoc.SelectNodes("configuration/ServersSection/servergroups/server"))
                {
                    if (xn.Attributes[0].Value == ActiveServer.ServerName)
                    {
                        xDoc.SelectSingleNode("configuration/ServersSection/servergroups").RemoveChild(xn);
                        break;
                    }
                }

                xDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
                ConfigurationManager.RefreshSection("ServersSection");
                ClearTextboxes();
                LoadServerDetails();
                EnabledControls(true);
            }
        }

        private void frmServers_FormClosing(object sender, FormClosingEventArgs e)
        {
            frmMain main = (frmMain)Owner;
            // NOTE this is probably a complete misuse of the internal keyword to allow an action to occur on the parent form.
            // Maybe I should consider changing LoadServerList() to be an internal method and call that instead.
            main.btnRefresh_Click(sender, e); // Update main forms drop-down list of servers
        }
    }
}
